home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_12_09 / single2 / farheapb.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-07  |  5.7 KB  |  196 lines

  1. //  Listing 4
  2. //  farheapb.cpp
  3. //
  4. //  Copyright Singleton Systems Ltd 1994 
  5.                   
  6. #include    "stdafx.h"
  7. #include    <new.h>
  8. #include    "mobject.h"
  9. #include    "farheapb.h"
  10.  
  11. //  static pointers to the FarHeapBlock structures
  12. HGLOBAL FarHeapBlock::first_fhb = NULL;
  13. HGLOBAL FarHeapBlock::last_fhb = NULL; 
  14.  
  15. FP_FHB FarHeapBlock::GetHbFromHandle (HGLOBAL h)
  16. {
  17. FP_FHB p_fhb = (FP_FHB) GlobalLock (h);
  18. ASSERT (p_fhb != NULL);
  19. GlobalUnlock (h);
  20. return p_fhb;
  21. }
  22.  
  23. void FAR * FarHeapBlock::operator new 
  24.                         (size_t /* size */)
  25. //  We do not need to use the size parameter, 
  26. //  as we always allocate a fixed size of 
  27. //  FarHeapBlock::default_size bytes.
  28. {
  29. HGLOBAL h = GlobalAlloc 
  30.             (GMEM_MOVEABLE | GMEM_ZEROINIT,
  31.             FarHeapBlock::default_size);
  32. //  The GMEM_ZEROINIT is not strictly necessary, but 
  33. //  it seems a good idea to start off with the memory 
  34. //  in a defined state.  
  35.             
  36. //  #define    FHB_MEM_TEST
  37.                          
  38. //  For test purposes only, force a failure 
  39. //  if less than 5Mb memory free
  40. #if defined (FHB_MEM_TEST) && defined (_DEBUG)
  41. if (GetFreeSpace (0) < 5000000L)
  42.     {
  43.     //  Unable to get memory or not enough left to
  44.     //  handle recovery, so take some error action
  45.     
  46.     //  Get current new handler 
  47.     _PNH handler = _set_new_handler (0);
  48.     //  and restore it as the action of getting a 
  49.     //  pointer to it unsets it    
  50.     _set_new_handler (handler);
  51.     //  Signal the failure back up the chain.  
  52.     //  This should raise an Exception               
  53.     (* handler) (FarHeapBlock::default_size);    
  54.     //  Fail regardless of value returned by the 
  55.     //  handler
  56.     return NULL;
  57.     }
  58. #endif    
  59.                          
  60. ASSERT (h != NULL); 
  61. if (h == NULL || GetFreeSpace (0) < 10000L) 
  62.     {      
  63.     //  Unable to get memory or not enough left to
  64.     //  handle recovery, so take some error action
  65.     
  66.     //  Get current new handler 
  67.     _PNH handler = _set_new_handler (0);
  68.     //  and restore it as the action of getting a 
  69.     //  pointer to it unsets it    
  70.     _set_new_handler (handler);
  71.     //  Signal the failure back up the chain.  
  72.     //  This should raise an Exception               
  73.     (* handler) (FarHeapBlock::default_size);    
  74.     //  Fail regardless of value returned by the 
  75.     //  handler
  76.     return NULL;
  77.     }
  78. else 
  79.     {
  80.     FP_FHB p_fhb = (FP_FHB) GlobalLock (h);
  81.     p_fhb->my_hglobal = h; 
  82.     p_fhb->fhb_block_size = GlobalSize (h);
  83.     
  84.     //  Now chain the block into the list of blocks
  85.     if (IsEmpty ())
  86.         {
  87.         ASSERT (last_fhb == NULL);
  88.         first_fhb = last_fhb = h;
  89.         }                       
  90.     else
  91.         {
  92.         FP_FHB p_last_fhb = 
  93.             FarHeapBlock::GetHbFromHandle (last_fhb);
  94.         p_last_fhb->next_hglobal = h;
  95.         p_fhb->previous_hglobal = last_fhb;
  96.         p_fhb->next_hglobal = NULL; 
  97.         last_fhb = h;
  98.         }    
  99.     return p_fhb;                         
  100.     }
  101. }  
  102.  
  103. void FarHeapBlock::operator delete (void FAR * p_fhb)
  104. {
  105. ASSERT (p_fhb != NULL);
  106. ASSERT (OFFSETOF (p_fhb) == 0);
  107. FP_FHB current_block_pointer = (FP_FHB) p_fhb;
  108.  
  109. #if defined (_DEBUG)
  110. FP_FHB check = FarHeapBlock::GetHbFromHandle 
  111.                 (current_block_pointer->my_hglobal);
  112. ASSERT (check == current_block_pointer);
  113. #endif
  114.  
  115. //  Reset the pointers in the previous block
  116. if (current_block_pointer->previous_hglobal != NULL)
  117.     {
  118.     FP_FHB prev_ptr = GetHbFromHandle 
  119.             (current_block_pointer->previous_hglobal);
  120.     prev_ptr->next_hglobal = 
  121.             current_block_pointer->next_hglobal;
  122.     }
  123. else    //  This should be the first block in the list
  124.     {
  125.     ASSERT (current_block_pointer->my_hglobal == 
  126.             FarHeapBlock::first_fhb);
  127.     FarHeapBlock::first_fhb = 
  128.             current_block_pointer->next_hglobal;
  129.     }       
  130.                                   
  131. //  Reset the pointers in the next block
  132. if (current_block_pointer->next_hglobal != NULL)
  133.     {
  134.     FP_FHB next_ptr = 
  135.             FarHeapBlock::GetHbFromHandle 
  136.                 (current_block_pointer->next_hglobal);
  137.     next_ptr->previous_hglobal = 
  138.             current_block_pointer->previous_hglobal;
  139.     }
  140. else    //  This should be the last block in the list
  141.     {
  142.     ASSERT (current_block_pointer->my_hglobal == 
  143.             FarHeapBlock::last_fhb);
  144.     FarHeapBlock::last_fhb = 
  145.             current_block_pointer->previous_hglobal;
  146.     } 
  147.  
  148. //  The block has been unlinked, so return it to 
  149. //  Windows
  150. GlobalUnlock (current_block_pointer->my_hglobal);
  151. GlobalFree (current_block_pointer->my_hglobal);    
  152.  
  153. FarHeapBlock::FarHeapBlock ()
  154. {
  155. //  fhb_block_size set by new!
  156.  
  157. //  A FarHeapBlock is requested directly from 
  158. //  Windows.  Windows supplies
  159. //  a segment with offsets starting at 0. 
  160. __segment cur_seg = (__segment) SELECTOROF (this);
  161.  
  162. //  Mark all of the free space in the FarHeapBlock 
  163. //  as a single, free MemoryObject
  164. free_list = end_free_list = 
  165.                 (VP_MOBJECT) sizeof(FarHeapBlock);
  166.  
  167. in_use_list = NULL;
  168. end_in_use_list = NULL;
  169. (cur_seg:>free_list)->SetFirstMemoryObject 
  170.             (my_hglobal, 
  171.             (int) Size () - sizeof(FarHeapBlock));
  172. }
  173.  
  174. int FarHeapBlock::GetCount ()
  175. {   
  176. int usage_count = 0;;
  177. HGLOBAL current_block = FarHeapBlock::first_fhb;
  178. while (current_block != NULL)
  179.     {
  180.     FP_FHB p_fhb = GetHbFromHandle (current_block);
  181.     usage_count++;
  182.     current_block = p_fhb->next_hglobal;
  183.     }
  184. return usage_count;
  185. }
  186.  
  187. FP_FHB FarHeapBlock::GetNext (FHB_POSITION & p)
  188. {
  189. ASSERT (p != NULL);
  190. FP_FHB p_fhb = GetHbFromHandle (p);
  191. p = p_fhb->next_hglobal;
  192. return p_fhb;
  193. }
  194.  
  195.